package com.wangl.spring.declarationHandler;

import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.FileTypeIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.wangl.spring.service.ProjectSuggestionService;
import com.wangl.spring.suggestion.PropertiesManager;
import com.wangl.spring.suggestion.filetype.SpringConfigurationPropertiesFileType;
import com.wangl.spring.utils.PlaceholderResolver;
import com.wangl.spring.utils.PropertiesFileUtil;
import com.wangl.spring.utils.PsiCustomUtil;
import com.wangl.spring.utils.YamlFileUtil;
import org.jetbrains.annotations.Nullable;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName ValueAnnotationGotoDeclarationHandler
 * @Description @Value注解导航至配置文件
 * @Author wangl
 * @Date 2023/4/26 18:14
 */
public class ValueAnnotationGotoDeclarationHandler implements GotoDeclarationHandler {

    @Override
    public PsiElement @Nullable [] getGotoDeclarationTargets(@Nullable PsiElement source, int offset, Editor editor) {
        Project project = editor.getProject();
        if (project == null){
            return new PsiElement[0];
        }
        if (isAnnotationPsiElement(source)){
            List<String> placeholders = PlaceholderResolver.getPlaceholders(source.getText());
            if (CollectionUtils.isEmpty(placeholders)){
                return new PsiElement[0];
            }
            Module module = PsiCustomUtil.findModule(source);
            if (Objects.isNull(module)){
                return new PsiElement[0];
            }
            GlobalSearchScope moduleScope = GlobalSearchScope.moduleScope(module);
            Set<PsiElement> resultSet = new HashSet<>();
            for (String placeholder : placeholders) {
                Set<PsiElement> propertiesElements = PropertiesFileUtil.findByKey(placeholder, moduleScope, project);
                resultSet.addAll(propertiesElements);
                Set<PsiElement> yamlElements = YamlFileUtil.findByKey(placeholder, moduleScope, project);
                resultSet.addAll(yamlElements);
            }
            return resultSet.toArray(new PsiElement[0]);
        }
        return new PsiElement[0];
    }

    private boolean isAnnotationPsiElement(PsiElement psiElement){
        PsiElement parent;
        return psiElement instanceof PsiJavaToken &&
                (parent = psiElement.getParent()) instanceof PsiLiteralExpression &&
                (parent = parent.getParent()) instanceof PsiNameValuePair &&
                (parent = parent.getParent()) instanceof PsiAnnotationParameterList &&
                parent.getParent() instanceof PsiAnnotation;
    }
}
